package com.itfreer.power;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.itfreer.power.entity.logging.LogInfo;
import com.itfreer.power.service.logging.LoggingService;
import com.itfreer.power.service.power.PowerService;
import com.itfreer.utils.filter.FilterInterception;
import com.itfreer.utils.filter.FilterResult;
import com.itfreer.utils.filter.UrlMatchUtils;

/**
 * 系统权限过滤器
 */
public class ServicePowerFilterInterception implements FilterInterception {

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired(required = false)
	private LoggingService loggingService;
	@Autowired
	private PowerService powerService;

	private int index;
	
	@Override
	public Integer getIndex() {
		return index;
	}

	@Override
	public void setIndex(Integer index) {
		this.index = index;
	}

	/**
	 * 过滤
	 * 
	 * @param request
	 * @param response
	 * @return true 同意继续下个过滤器，false 不处理后续过滤器
	 */
	@Override
	public FilterResult doFilter(HttpServletRequest request, HttpServletResponse response, String servletPath) {
		String sid = request.getHeader("sid");
		String spwd = request.getHeader("spwd");

		// 如果不是，则继续
		if (sid == null || spwd == null) {
			return new FilterResult();
		}

		return urlResourceDecide(request, response, sid, spwd, servletPath);
	}

	/**
	 * 决策资源
	 */
	private FilterResult urlResourceDecide(HttpServletRequest request, HttpServletResponse response, String sid, String spwd,
			String rqUrl) {
		// 准备日志
		LogInfo info = new LogInfo();
		info.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		info.setFunName(rqUrl);
		info.setFunType("功能访问");
		info.setTime(new Date());
		info.setIp("");
				
		List<String> canAccessUrl = powerService.getSysUrls(sid, spwd);
		if (canAccessUrl == null || canAccessUrl.size() <= 0) {
			info.setInfo("可访问地址为空！");
			info.setResult("失败");
			logging(info);

			logger.debug("访问【" + rqUrl + "】权限不够，可访问地址为空。");
			try {
				response.sendError(400, "访问权限不够！");
			} catch (IOException e) {
				e.printStackTrace();
			}
			return new FilterResult(true, true);
		} else {
			if (exclude(canAccessUrl, rqUrl)) {
				info.setInfo(null);
				info.setResult("成功");
				logging(info);
				return new FilterResult(false, true);
			} else {
				info.setInfo("没有可访问权限！");
				info.setResult("失败");
				logging(info);
				logger.debug("访问【" + rqUrl + "】权限不够，没有可访问权限。");
				try {
					response.sendError(400, "访问权限不够！");
				} catch (IOException e) {
					e.printStackTrace();
				}
				return new FilterResult(true, true);
			}
		}
	}

	/**
	 * 是否匹配
	 * 
	 * @param url
	 * @return
	 */
	private boolean exclude(List<String> excludeUrls, String url) {
		// 过滤模式，过滤掉无需保护资源
		for (String pattern : excludeUrls) {
			if (UrlMatchUtils.match(pattern, url)) {
				return true;
			}
		}
		return false;
	}

	private void logging(LogInfo info) {
		if (loggingService == null) {
			logger.debug("loggingService为null");
			return;
		}
		LoggingThread loggingThread = new LoggingThread(info);
		loggingThread.start();
	}

	private class LoggingThread extends Thread {
		private LogInfo info;

		public LoggingThread(LogInfo info) {
			this.info = info;
		}

		public void run() {
			loggingService.logging(info);
		}
	}
}